package com.rongxun.utils;

import com.rongxun.hbwallet.model.Response;
import com.rongxun.http.ResponseCode;
import com.rongxun.http.exception.ApiException;
import com.rongxun.http.exception.EmptyDataException;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * @author forza
 * @classname: RxUtil
 * @Description:
 * @date 2017/4/11 17:39
 */
public class RxUtil {

    /**
     * 统一线程处理
     *
     * @param <T>
     * @return
     */
    public static <T> FlowableTransformer<T, T> rxSchedulerHelper() {    //compose简化线程
        return observable -> observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    /**
     * 统一处理返回结果为BaseResponse的请求
     *
     * @param <T>
     * @return
     */
    public static <T> FlowableTransformer<Response<T>, T> handleResult() {   //compose判断结果
        return upstream -> upstream.flatMap((Function<Response<T>, Flowable<T>>) tBaseResponse -> {
            if (ResponseCode.SUCCESS.equals(tBaseResponse.getCode())) {
                T t = tBaseResponse.getData();
                if (t == null) {
                    return Flowable.error(new EmptyDataException("there is nothing"));
                }
                return createData(tBaseResponse.getData());
            } else {
                return Flowable.error(new ApiException(tBaseResponse.getMessage(), tBaseResponse.getCode()));
            }
        });
    }

    /**
     * 统一处理返回结果为BaseResponse并且不需要关注result结果的请求
     *
     * @param <T>
     * @return
     */
    public static <T> FlowableTransformer<Response, Boolean> handleBaseResponse() {   //compose判断结果
        return upstream -> upstream.flatMap((Function<Response, Flowable<Boolean>>) tBaseResponse -> {
            if (ResponseCode.SUCCESS.equals(tBaseResponse.getCode())) {
                return createData(true);
            } else {
                return Flowable.error(new ApiException(tBaseResponse.getMessage(), tBaseResponse.getCode()));
            }
        });
    }

    /**
     * 生成Flowable
     *
     * @param <T>
     * @return
     */
    public static <T> Flowable<T> createData(final T t) {
        return Flowable.create(emitter -> {
            try {
                emitter.onNext(t);
                emitter.onComplete();
            } catch (Exception e) {
                emitter.onError(e);
            }
        }, BackpressureStrategy.BUFFER);
    }
}
